
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;

public class HelicopterSprite extends Sprite {

	private boolean m_isFlying = false;
    private int m_Direction;
    private int mKX,  mKY;
    private int mLastDifference;
    private boolean mLastWT;
    private int m_speed = STOP;
    private boolean m_turning = false;
    private HeliChangeListener m_speedListener;
    
    
    public static int FORWARD = 0;
    public static int BACKWARD = 1;
    public static int STOP = 2;
    
    private static final int[] kTransformLookup = {
        Sprite.TRANS_NONE, Sprite.TRANS_NONE, Sprite.TRANS_NONE,
        Sprite.TRANS_MIRROR_ROT90,
        Sprite.TRANS_ROT90, Sprite.TRANS_ROT90, Sprite.TRANS_ROT90,
        Sprite.TRANS_MIRROR_ROT180,
        Sprite.TRANS_ROT180, Sprite.TRANS_ROT180, Sprite.TRANS_ROT180,
        Sprite.TRANS_MIRROR_ROT270,
        Sprite.TRANS_ROT270, Sprite.TRANS_ROT270, Sprite.TRANS_ROT270,
        Sprite.TRANS_MIRROR
    };
    private static final int[] kFrameLookup = {
        0, 1, 2, 1,
        0, 1, 2, 1,
        0, 1, 2, 1,
        0, 1, 2, 1
    };
    private static final int[] kxLookup = {
        0, 383, 707, 924,
        1000, 924, 707, 383,
        0, -383, -707, -924,
        -1000, -924, -707, -383
    };
    private static final int[] kyLookup = {
        1000, 924, 707, 383,
        0, -383, -707, -924,
        -1000, -924, -707, -383,
        0, 383, 707, 924
    };

    public HelicopterSprite(Image image, int frameWidth, int frameHeight) {
        super(image, frameWidth, frameHeight);
        defineReferencePixel(frameWidth / 2, frameHeight / 2);
        m_Direction = 0;
    }

    public void turn(int difference) {
        m_Direction += difference;
        if (m_Direction < 0) {
            m_Direction += 16;
        }
        if (m_Direction > 15) {
            m_Direction %= 16;
        }
        setFrame(kFrameLookup[m_Direction]);
        setTransform(kTransformLookup[m_Direction]);

        mLastDifference = difference;
        mLastWT = true;
    }

    public void forward(int delta) {
        fineMove(kxLookup[m_Direction] * delta,
                -kyLookup[m_Direction] * delta);
        mLastDifference = delta;
        mLastWT = false;
    }

    public void undo() {
        if (mLastWT) {
            turn(-mLastDifference);
        } else {
            forward(-mLastDifference);
        }
    }

    private void fineMove(int kx, int ky) {
        // First initialize mKX and mKY if they're
        // not close enough to the actual x and y.
        int x = getX();
        int y = getY();
        int errorX = Math.abs(mKX - x * 1000);
        int errorY = Math.abs(mKY - y * 1000);
        if (errorX > 1000 || errorY > 1000) {
            mKX = x * 1000;
            mKY = y * 1000;
        }
        // Now add the differences.
        mKX += kx;
        mKY += ky;
        // Set the actual position.
        setPosition(mKX / 1000, mKY / 1000);
    }

	public int getDirection() {
		return m_Direction;
	}

	public void setDirection(int direction) {
		m_Direction = direction;
	}

	public boolean isFlying() {
		return m_isFlying;
	}

	public void setFlying(boolean flying) {
		m_isFlying = flying;
	}

	public int getSpeed() {
		return m_speed;
	}

	public void setSpeed(int speed) {
		if (speed != m_speed) {
			this.m_speed = speed;
			if (speed == STOP)
				stopAcc();
			else
				beginAcc();
		}
	}
	
	public boolean isTurning(){
		return m_turning;
	}
	
	public void setTurning(boolean turning){
		if (turning != m_turning){
			m_turning = turning;
			if (turning){
				beginTurn();
			}else{
				stopTurn();
			}
		}
	}

	public void setSpeedListener(HeliChangeListener listener) {
		m_speedListener = listener;
	}
	
	private void beginAcc() {
		if (m_speedListener != null) {
			m_speedListener.onHeliBeginsAccelerate(this);
		}
	}
	
	private void stopAcc() {
		if (m_speedListener != null) {
			m_speedListener.onHeliStopsAccelerate(this);
		}
	}
	
	private void beginTurn(){
		if (m_speedListener != null){
			m_speedListener.onHeliBeginsTurn(this);
		}
	}
	
	private void stopTurn(){
		if (m_speedListener != null){
			m_speedListener.onHeliStopsTurn(this);
		}
	}

}
